#ifndef GRAF
#define GRAF

#include <math.h>
#include <GL/glut.h> 

#include "general.h"
#include "miscfunc.h"
#include "messages.h"

struct point
{
	double x,y;
};

class grafico
{
private:
	int inicio, //aponta para o inicio da sequencia em data
		tam,	//armazena o tamanho da sequencia
		num;	//numero maximo de amostras por grafico (maior maximo=1000)
	point data[1000];	//dados armazenados
	char title[80],		//titulo do grafico
		 xaxis[80],		//nome do eixo x
		 yaxis[80];		//nome do eixo y
	double aymax, aymin, ystep;	//range dos valores
	double axmax, axmin;	//range dos valores

public:	
	bool ciclo;					//flag para indicar se o grafico deve ser apagado quando completo
								//ou deve ser rolado. false=rolado
	bool points;	// points=true - grafico de pontos / false - grafico de linhas

	void settitle(char *nome);
	void setyaxisname(char *nome);
	void setyaxislimit(double max, double min);
	void setyaxisstep(double stp);
	void setxaxisname(char *nome);
	void setxaxislimit(double max, double min);
	void setpoints(int n);
	void addpoint(double ptx, double pty);
	void init();
	void drawpoints(double xorg, double yorg, double maxx, double maxy);
	void drawaxis(double xorg, double yorg, double maxx, double maxy);
	void drawnames(double xorg, double yorg, double maxx, double maxy);
	point export(int i);
	~grafico(void);
};

grafico::~grafico(void)
{
	printf(MSG65,title);
}

void grafico::settitle(char *nome)
{
	strcpy(title, nome);
}

void grafico::setyaxisname(char *nome)
{
	strcpy(yaxis, nome);
}

void grafico::setyaxislimit(double max, double min)
{
	aymax=max;
	aymin=min;
}

void grafico::setyaxisstep(double stp)
{
	ystep=stp;
}

void grafico::setxaxisname(char *nome)
{
	strcpy(xaxis, nome);
}

void grafico::setxaxislimit(double max, double min)
{
	axmax=max;
	axmin=min;
}

void grafico::setpoints(int n)
{
	num=n;
}

void grafico::addpoint(double ptx,double pty)
{
	data[inicio].x=ptx;
	data[inicio].y=pty;
	inicio++;
	if (ciclo) 	
	{
		if (inicio==num) init();
	}
	else
	{
		if (inicio==num) inicio=0;
		if (tam<num) 
		{
			tam++;
			if(axmax<ptx) setxaxislimit(ptx,axmin);
		}
		else
		{
			setxaxislimit(ptx,data[inicio].x);
		}

	}
}

void grafico::init(void)
{
	inicio=0;
	tam=0;
}

void grafico::drawpoints(double xorg, double yorg, double maxx, double maxy)
{
	int i;
	int desl;
	double multx,multy;
	double orx,ory;

	multx=maxx/(axmax-axmin);
	multy=maxy/(aymax-aymin);
	
	orx=xorg-axmin*multx;
	ory=yorg-aymin*multy;
	
	if (points)
		glBegin(GL_POINTS);
	else
		glBegin(GL_LINE_STRIP);
	
	if(tam==num)
	for(i=0;i<tam;i++)
	{
		if(i+inicio>=tam) desl=-tam; else desl=0;
		glVertex2f(orx+data[i+inicio+desl].x*multx, ory+data[i+inicio+desl].y*multy);
	}
	else
	for(i=0;i<tam;i++)
	{
		glVertex2f(orx+data[i].x*multx, ory+data[i].y*multy);
	}
	glEnd();
}

point grafico::export(int i)
{
	int desl;
	point exp;

	if(i>=tam) 
	{
		exp.x=-1;
		exp.y=0;
		return exp;
	}
	if(tam==num)
	{
		if(i+inicio>=tam) desl=-tam; else desl=0;
		exp=data[i+inicio+desl];
	}
	else
	{
		exp=data[i];
	}
	return exp;
}

void grafico::drawaxis(double xorg, double yorg, double maxx, double maxy)
{
	double multx,multy;
	double orx,ory;
	int inic,fim;
	double i;
	double aux1,aux2;
	char temp[20];
	bool plot=true;
	
	multx=maxx/(axmax-axmin);
	multy=maxy/(aymax-aymin);
	
	orx=xorg-axmin*multx;
	ory=yorg-aymin*multy;

	glBegin(GL_LINES);
		if(ory>=yorg)
		{
			glVertex2f(xorg,ory);
			glVertex2f(orx+axmax*multx,ory);
		}
		else 
		{
			glVertex2f(xorg,yorg);
			glVertex2f(orx+axmax*multx,yorg);
		}
		glVertex2f(xorg,yorg);
		glVertex2f(xorg,ory+aymax*multy);
	glEnd();

	inic=1+(int)axmin;
	fim=(int)axmax;
	if(ory>=yorg)
		aux2=ory;
	else 
		aux2=yorg;
	for(i=inic;i<fim;i++)
	{
		aux1=orx+i*multx;
		glBegin(GL_LINES);
			glVertex2f(aux1,aux2+2);
			glVertex2f(aux1,aux2-2);
		glEnd();
		if (!((long int)i%2)) 
		{
			sprintf(temp,"%ld",(long int)i);
			outtext(CENTER, ESC_FONT, aux1, aux2-10,temp);
		}
	}

	inic=(int)aymin;
	fim=(int)aymax;
	for(i=inic;i<fim;i+=ystep)
	{
		aux1=ory+i*multy;
		glBegin(GL_LINES);
			glVertex2f(xorg+2, aux1);
			glVertex2f(xorg-2, aux1);
		glEnd();
		if(plot)
		{
			if (fabs(i)>=1) sprintf(temp,"%ld",(long int)i);
			else sprintf(temp,"%1.3lf",i);
			outtext(RIGHT, ESC_FONT, xorg-4, aux1-2, temp);
		}
		plot=!plot;
	}
}

void grafico::drawnames(double xorg, double yorg, double maxx, double maxy)
{
	double auxx,auxy;
		
	auxx=xorg+maxx/2;
	auxy=yorg+maxy/2;

	//outtext(CENTER, ESC_FONT, auxx, yorg+maxy+5, title );
	outtext(CENTER, ESC_FONT, auxx, yorg-9, xaxis);
	outtext(RIGHT, ESC_FONT, xorg-5, yorg+maxy-5, yaxis);
}

#endif




